import 'package:aio/aio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:app/generated/app_strings.dart';
import 'package:app/src/ui/app_ui.dart';
import 'package:flutter_html/flutter_html.dart' as html;

class UiBase {
  ///判断数据是否发生变化；true 老旧数据不同；false 相同。
  ///isForceCompare 是否强制对比，新旧数据只要不一样就对比。（null和空字符也对比）
  static bool isNotSame(String? data, String? oldData,
      {bool isForceCompare = false}) {
    if (StringUtils.isEmpty(oldData)) {
      if (isForceCompare) {
        //需要强制作对比
      } else {
        return false; //fixme 旧数据如果为空；就表示没有不同；就不用对比了。
      }
    }
    bool b = StringUtils.isNotSame(data, oldData);
    return b;
  }

  ///判断数据是否为是
  static bool isYes(String? data) {
    if (data != null && data.trim() == "是") {
      return true;
    }
    return false;
  }

  ///标题
  static Widget title(BuildContext context, String? title,
      {double bottom = 0, bool titleRed = false}) {
    TextStyle textStyle = AppStyle.textStyleWithCardTitle();
    if (titleRed) {
      textStyle = AppStyle.textStyleWithCardTitleRed();
    }
    var text = Text(
      title ?? "",
      style: textStyle,
    );
    return Container(
      child: Row(
        children: [text],
      ),
      margin: EdgeInsets.only(bottom: bottom),
    );
  }

  // static var _width = px.screenWidth() / 3;
  static var _width =
      px.screenWidth() / 2; //fixme 防止左边显示不全，给左边宽度加大一点。左边不会自动换行，右边文本会自动换行。
  static var _padding = 8.0;

  static setWidth() {
    _width = px.screenWidth() / 2;
  }

  ///普通文本；一行显示两个文本。
  ///key 名称
  ///value 数据
  ///oldValue 老数据，用于判断数据是否发生过更新
  ///unit 单位，如："m²"
  ///isBlue 是否为蓝色字体
  ///isNew 是否为新，突出显示。
  ///isAllowEmpty 是否允许为空,默认允许；（false 不允许的话，文本为空，则不会显示该行）
  ///isGrey 灰色文本
  ///isStart 是否带星号*
  ///isChangeColor 是否对新旧值对比，突然颜色变化。
  ///isShowOldValue 是否显示旧文本。
  ///isForceCompare 是否强制对比，新旧数据只要不一样就对比。（null和空字符也对比）
  static Widget item(
    BuildContext context,
    String? key,
    String? value,
    String? oldValue, {
    String unit = "",
    Widget? sufix = null,
    bool isBlue = false,
    bool isNew = false,
    bool isHtml = false,
    bool isGrey = false,
    bool isStart = false,
    bool isChangeColor = true,
    double? topPadding = null,
    GestureTapCallback? onTap,
    bool isAllowEmpty = true,
    String defaultValue = "",
    bool isShowOldValue = true,
    bool isForceCompare = false,
  }) {
    if (!isAllowEmpty) {
      //不允许为空
      if (StringUtils.isEmpty(value)) {
        return AppUi.getEmptyView(); //数据为空，返回空布局。
      }
    }
    if (topPadding == null) {
      topPadding = _padding;
    }
    TextStyle textStyle = AppStyle.textStyleWithCard();
    bool isRed = false; //fixme 判断新旧数据是否一致。
    if (isChangeColor && isNotSame(value, oldValue)) {
      //文本有变化，用红色标记。
      textStyle = AppStyle.textStyleWithCardRed();
      isRed = true;
    }
    if (isChangeColor && !isRed && isForceCompare) {
      isRed = isNotSame(value, oldValue,
          isForceCompare: isForceCompare); //fixme 空数据也对对比判断。
    }
    if (isBlue) {
      textStyle = AppStyle.textStyleWithCardBlue();
    }
    if (isGrey) {
      textStyle = AppStyle.textStyleWithCardGrey();
    }
    Widget? child = null;
    if (isHtml) {
      child = html.Html(
        data: (value ?? ""),
      );
    } else {
      Widget textValue;
      if (StringUtils.isEmpty(value)) {
        textValue = Text(
          defaultValue,
          softWrap: true,
          //maxLines: 10,//fixme 之前就因为这个导致文本显示不全。
          style: textStyle,
        );
        child = textValue;
      } else {
        textValue = Text(
          (value ?? defaultValue) + unit,
          softWrap: true,
          //maxLines: 10,//fixme 之前就因为这个导致文本显示不全。
          style: textStyle,
        );
        child = textValue;
      }
      if (onTap != null) {
        child = InkWell(
          child: textValue!,
          onTap: onTap,
        );
      } else {
        if (isRed && isShowOldValue) {
          child = UiBase.itemWithCompare(
              context,
              "${(value ?? defaultValue) + unit}",
              "${(oldValue ?? defaultValue) + unit}",
              horizon: false,
              //水平显示不全，改成垂直比较好。
              isCenter: false,
              isForceCompare: isForceCompare); //fixme 这里，保留新旧文本。
        }
      }
    }
    List<Widget> children = [];
    if (!StringUtils.isEmpty(key)) {
      key = key! + ":";
    }
    if (isStart) {
      var textKey = Text(
        key ?? "",
        style: AppStyle.textStyleWithCard(),
      );
      var value = "*";
      var startText = Text(
        value,
        softWrap: true,
        style: AppStyle.textStyleWithCardRed(),
      );
      children.add(SizedBox(
        child: Row(
          children: [textKey, startText],
        ),
        width: _width,
      ));
    } else {
      var textKey = Text(
        key ?? "",
        style: AppStyle.textStyleWithCard(),
      );
      children.add(SizedBox(
        child: textKey,
        width: _width,
      ));
    }

    if (isNew) {
      var value = AppStrings.of(context).New;
      var newText = Text(
        value,
        softWrap: true,
        style: AppStyle.textStyleWithCardWhite(),
      );
      children.add(Container(
          child: newText,
          alignment: Alignment.center,
          //width: 40,
          padding: EdgeInsets.only(left: 8, right: 8, top: 0, bottom: 0),
          margin: EdgeInsets.only(right: 8),
          decoration: BoxDecoration(
              //border: Border.all(color: Colors.grey,width: 1)
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(10.0),
                  bottomLeft: Radius.zero,
                  topRight: Radius.circular(10.0),
                  bottomRight: Radius.circular(10.0)),
              color: Colors.red)));
    }
    if (sufix != null) {
      children.add(Expanded(
          child: Row(
        children: [child, sufix],
      )));
    } else {
      children.add(Expanded(child: child));
    }
    var row = Row(children: children
        // [
        //   SizedBox(
        //     child: textKey,
        //     width: _width,
        //   ),
        //   Expanded(child: child)
        // ],
        );
    return Padding(
      padding: EdgeInsets.only(top: topPadding),
      child: row,
    );
  }

  static Widget itemWithYes(BuildContext context, String? key, String? value,
      {String unit = ""}) {
    if (StringUtils.isEmpty(value)) {
      return AppUi.getEmptyView(); //数据为空，返回空布局。
    }
    var textKey = Text(
      key ?? "",
      style: AppStyle.textStyleWithCard(),
    );
    TextStyle textStyle = AppStyle.textStyleWithCard();
    if (isYes(value)) {
      //文本有变化，用红色标记。
      textStyle = AppStyle.textStyleWithCardRed();
    }
    var textValue = Text(
      (value ?? "") + unit,
      softWrap: true,
      maxLines: 3,
      style: textStyle,
    );
    var row = Row(
      children: [
        SizedBox(
          child: textKey,
          width: _width,
        ),
        Expanded(child: textValue)
      ],
    );
    return Padding(
      padding: EdgeInsets.only(top: _padding),
      child: row,
    );
  }

  ///普通文本;一行显示一个文本。
  ///value 数据
  ///oldValue 老数据，用于判断数据是否发生过更新
  static Widget itemWithSingle(
      BuildContext context, String? value, String? oldValue) {
    TextStyle textStyle = AppStyle.textStyleWithCard();
    if (isNotSame(value, oldValue)) {
      //文本有变化，用红色标记。
      textStyle = AppStyle.textStyleWithCardRed();
    }
    var textValue = Text(
      value?.trim() ?? "",
      softWrap: true,
      maxLines: 14,
      style: textStyle,
    );
    // var row = Row(
    //   children: [textValue],
    // );
    return Padding(
      padding: EdgeInsets.only(top: _padding),
      child: textValue,
    );
  }

  ///普通文本输入框；一行显示两个文本。
  ///key 名称
  ///value 数据
  ///oldValue 老数据，用于判断数据是否发生过更新
  ///unit 单位，如："m²"
  ///isBlue 是否为蓝色字体
  ///isNew 是否为新，突出显示。
  ///isChangeColor 是否对新旧值对比，突然颜色变化。
  ///isNumber 数字类型
  ///isDecimal 小数类型
  ///isEmpty 是否允许文本为空；true 文本为空；也会显示该行；false 文本为空不会显示。
  ///isNegative 是否允许为负数
  ///isAllowEmpty 是否允许为空
  static Widget itemWithEdit(
      BuildContext context, String? key, String? value, String? oldValue,
      {String? unit = "",
      bool isBlue = false,
      bool isNew = false,
      bool isChangeColor = true,
      bool isNumber = false,
      bool isDecimal = false,
      bool isNegative = true,
      double? topPadding = null,
      bool isEmpty = false,
      bool isAllowEmpty = false,
      bool readOnly = false,
      FocusNode? focusNode = null,
      Widget? suffixIcon = null,
      ValueChanged<String>? onChanged}) {
    if (suffixIcon != null) {
      unit = null;
    }
    if (!isAllowEmpty) {
      if (StringUtils.isEmpty(value) && !isEmpty) {
        return AppUi.getEmptyView(); //数据为空，返回空布局。
      }
    }
    if (topPadding == null) {
      topPadding = _padding;
    }
    if (!StringUtils.isEmpty(key)) {
      key = key! + ":";
    }
    var textKey = Text(
      key ?? "",
      style: AppStyle.textStyleWithCard(),
    );
    TextStyle textStyle = AppStyle.textStyleWithCard();
    if (isNotSame(value, oldValue) && isChangeColor) {
      //文本有变化，用红色标记。
      textStyle = AppStyle.textStyleWithCardRed();
    }
    if (isBlue) {
      textStyle = AppStyle.textStyleWithCardBlue();
    }
    // var textValue = Text(
    //   (value ?? "") + unit,
    //   softWrap: true,
    //   maxLines: 10,
    //   style: textStyle,
    // );
    var content = value ?? "";
    var _serverTextEditingController = TextEditingController.fromValue(
      TextEditingValue(
          text: content,
          selection: TextUtils.setTextSelection(position: content.length)),
    );
    var textValue = StatefulBuilder(
      builder: (context, setState) {
        if (isDecimal) {
          return TextField(
            //cursorColor: AppUiConfig.themeColorWithServerAdress,//鼠标颜色
            controller: _serverTextEditingController,
            //文本控制器
            style: textStyle,
            inputFormatters: [
              DecimalFormatter(isEmpty: true, isNegative: isNegative)
            ],
            //fixme 只能输入数字类型
            keyboardType: TextInputType.number,
            //fixme 数字软键盘
            onChanged: (value) {
              //文本发生变化
              setState(() {
                onChanged?.call(value);
              });
            },
            focusNode: focusNode,
            readOnly: readOnly,
            decoration: InputDecoration(
                //hintText: AppStrings.of(context).serverAddress,//默认文本
                focusedBorder: UnderlineInputBorder(
                    borderRadius: BorderRadius.all(Radius.circular(0)),
                    borderSide: BorderSide(color: Colors.blueAccent, width: 1)),
                suffixText: unit,
                suffixIcon: suffixIcon),
          );
        }
        if (isNumber) {
          return TextField(
            //cursorColor: AppUiConfig.themeColorWithServerAdress,//鼠标颜色
            controller: _serverTextEditingController,
            //文本控制器
            style: textStyle,
            inputFormatters: [
              NumberFormatter(isEmpty: true, isNegative: isNegative)
            ],
            //fixme 只能输入数字类型
            keyboardType: TextInputType.number,
            //fixme 数字软键盘
            onChanged: (value) {
              //文本发生变化
              setState(() {
                onChanged?.call(value);
              });
            },
            focusNode: focusNode,
            readOnly: readOnly,
            decoration: InputDecoration(
              suffixText: unit, suffixIcon: suffixIcon,
              //hintText: AppStrings.of(context).serverAddress,//默认文本
              focusedBorder: UnderlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(0)),
                  borderSide: BorderSide(color: Colors.blueAccent, width: 1)),
            ),
          );
        }
        return TextField(
          //cursorColor: AppUiConfig.themeColorWithServerAdress,//鼠标颜色
          controller: _serverTextEditingController,
          //文本控制器
          style: textStyle,
          onChanged: (value) {
            //文本发生变化
            setState(() {
              onChanged?.call(value);
            });
          },
          focusNode: focusNode,
          readOnly: readOnly,
          decoration: InputDecoration(
            suffixText: unit, suffixIcon: suffixIcon,
            //hintText: AppStrings.of(context).serverAddress,//默认文本
            focusedBorder: UnderlineInputBorder(
                borderRadius: BorderRadius.all(Radius.circular(0)),
                borderSide: BorderSide(color: Colors.blueAccent, width: 1)),
          ),
        );
      },
    );
    Widget child = textValue;
    List<Widget> children = [];
    children.add(SizedBox(
      child: textKey,
      width: _width,
    ));
    if (isNew) {
      var value = AppStrings.of(context).New;
      var newText = Text(
        value,
        softWrap: true,
        style: AppStyle.textStyleWithCardWhite(),
      );
      children.add(Container(
          child: newText,
          alignment: Alignment.center,
          //width: 40,
          padding: EdgeInsets.only(left: 8, right: 8, top: 0, bottom: 0),
          margin: EdgeInsets.only(right: 8),
          decoration: BoxDecoration(
              //border: Border.all(color: Colors.grey,width: 1)
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(10.0),
                  bottomLeft: Radius.zero,
                  topRight: Radius.circular(10.0),
                  bottomRight: Radius.circular(10.0)),
              color: Colors.red)));
    }
    children.add(Expanded(child: child));
    var row = Row(children: children
        // [
        //   SizedBox(
        //     child: textKey,
        //     width: _width,
        //   ),
        //   Expanded(child: child)
        // ],
        );
    return Padding(
      padding: EdgeInsets.only(top: topPadding),
      child: row,
    );
  }

  ///普通文本输入框；一行显示一个文本。
  ///value 数据
  ///unit 单位，如："m²"
  ///isBlue 是否为蓝色字体
  ///isNew 是否为新，突出显示。
  ///isChangeColor 是否对新旧值对比，突然颜色变化。
  ///isNumber 数字类型
  ///isDecimal 小数类型
  ///max 最大值限制，isDecimal 为true时有效。
  ///isEmpty 是否允许文本为空；true 文本为空；也会显示该行；false 文本为空不会显示。
  ///isNegative 是否允许为负数
  ///isAllowEmpty 是否允许为空
  ///isLine true 文本输入框，底部为横线，falde 为矩形。
  static Widget itemWithSigleEdit(BuildContext context, String? value,
      {String? unit = "",
      bool isBlue = false,
      bool isRed = false,
      bool isChangeColor = true,
      bool isNumber = false,
      bool isDecimal = false,
      String? max,
      bool isNegative = true,
      double? topPadding = null,
      bool isEmpty = false,
      bool isAllowEmpty = false,
      bool isLine = true,
      bool readOnly = false,
      FocusNode? focusNode = null,
      ValueChanged<String>? onChanged,
      ValueChanged<TextEditingController?>? onController,
      TextSelection? mtextSelection,
      Key? key}) {
    if (!isAllowEmpty) {
      if (StringUtils.isEmpty(value) && !isEmpty) {
        return AppUi.getEmptyView(); //数据为空，返回空布局。
      }
    }
    if (topPadding == null) {
      topPadding = _padding;
    }
    TextStyle textStyle = AppStyle.textStyleWithCard();
    if (isBlue) {
      textStyle = AppStyle.textStyleWithCardBlue();
    }
    if (isRed) {
      textStyle = AppStyle.textStyleWithCardRed();
    }
    // var textValue = Text(
    //   (value ?? "") + unit,
    //   softWrap: true,
    //   maxLines: 10,
    //   style: textStyle,
    // );
    // print("================================文本输入框");
    var content = value ?? "";
    var _serverTextEditingController = TextEditingController.fromValue(
      TextEditingValue(
          text: content,
          selection: TextUtils.setTextSelection(position: content.length)),
    );
    var textAlign = TextAlign.center;
    var textAlignVertical = TextAlignVertical.center;
    var textValue = StatefulBuilder(
      builder: (context, setState) {
        InputDecoration? inputDecoration;
        if (isLine) {
          inputDecoration = InputDecoration(
              //hintText: AppStrings.of(context).serverAddress,//默认文本
              focusedBorder: UnderlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(0)),
                  borderSide: BorderSide(color: Colors.blueAccent, width: 1)),
              suffixText: unit,
              // counter: LibUi.getEmptyView(),
              counterStyle: TextStyle(
                height: double.minPositive, //fixme 隐藏计数器
              ),
              counterText: "");
        } else {
          inputDecoration = InputDecoration(
              contentPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(10.0))),
              // counter: Text(""),
              counterStyle: TextStyle(
                height: double.minPositive,
              ),
              counterText: "");
        }
        if (isDecimal) {
          var _controller = _serverTextEditingController;
          if (StringUtils.isNotEmpty(max)) {
            //最大值限制
            _controller = NumberLimitTextEditingController(
                max: max, min: "0", content: content);
          }
          if (mtextSelection != null) {
            try {
              _controller?.selection = mtextSelection!; //焦点位置
            } catch (e) {
              print("焦点位置异常：\t${e?.toString()}");
            }
          }
          onController?.call(_controller);
          return TextField(
            readOnly: readOnly,
            //cursorColor: AppUiConfig.themeColorWithServerAdress,//鼠标颜色
            controller: _controller,
            textAlign: textAlign,
            //fixme 数字类型，文本居中
            textAlignVertical: textAlignVertical,
            //文本控制器
            style: textStyle,
            inputFormatters: [
              DecimalFormatter(isEmpty: isAllowEmpty, isNegative: isNegative)
            ],
            //fixme maxLength 防止文本输入过大。
            maxLength: 15,
            maxLines: 1,
            //fixme 只能输入数字类型
            keyboardType: TextInputType.number,
            //fixme 数字软键盘
            onChanged: (value) {
              //文本发生变化
              // setState(() {
              //   if(_controller!=null){
              //     content=value;
              //   }
              //   onChanged?.call(value);
              // });
              //fixme 文本都会掉了，就不需要实时刷新这个界面了。
              if (_controller != null) {
                content = value;
              }
              onChanged?.call(value);
            },
            decoration: inputDecoration,
            focusNode: focusNode,
          );
        }
        if (isNumber) {
          if (mtextSelection != null) {
            _serverTextEditingController.selection = mtextSelection!; //焦点位置
          }
          return TextField(
            readOnly: readOnly,
            //cursorColor: AppUiConfig.themeColorWithServerAdress,//鼠标颜色
            controller: _serverTextEditingController,
            textAlign: textAlign,
            //fixme 数字类型，文本居中
            textAlignVertical: textAlignVertical,
            //文本控制器
            style: textStyle,
            inputFormatters: [
              NumberFormatter(isEmpty: isAllowEmpty, isNegative: isNegative)
            ],
            //fixme maxLength 防止文本输入过大。
            maxLength: 18,
            //fixme 只能输入数字类型
            keyboardType: TextInputType.number,
            //fixme 数字软键盘
            onChanged: (value) {
              //文本发生变化
              setState(() {
                onChanged?.call(value);
              });
            },
            decoration: inputDecoration,
            focusNode: focusNode,
          );
        }
        if (mtextSelection != null) {
          _serverTextEditingController.selection = mtextSelection!; //焦点位置
        }
        return TextField(
          readOnly: readOnly,
          //cursorColor: AppUiConfig.themeColorWithServerAdress,//鼠标颜色
          controller: _serverTextEditingController,
          textAlign: textAlign,
          //fixme 数字类型，文本居中
          textAlignVertical: textAlignVertical,
          //文本控制器
          style: textStyle,
          onChanged: (value) {
            //文本发生变化
            setState(() {
              onChanged?.call(value);
            });
          },
          decoration: inputDecoration,
          focusNode: focusNode,
        );
      },
    );
    Widget child = textValue;
    List<Widget> children = [];
    children.add(Expanded(child: child));
    var row = Row(children: children
        // [
        //   SizedBox(
        //     child: textKey,
        //     width: _width,
        //   ),
        //   Expanded(child: child)
        // ],
        );
    return Padding(
      key: key,
      padding: EdgeInsets.only(top: topPadding),
      child: ConstrainedBox(
        child: row,
        constraints: BoxConstraints(
          minWidth: 100, //最小宽度
          minHeight: 30.0, //最小高度
        ),
      ),
    );
  }

  ///文本对比，文本不同的显示新老旧数据。其中旧数据用红色标记
  ///isForceCompare 是否强制对比，true 强制对比，新旧数据只要不一样就对比。（null和空字符也对比）
  static Widget itemWithCompare(
      BuildContext context, String? value, String? oldValue,
      {bool horizon = true,
      bool isCenter = true,
      bool isForceCompare = false}) {
    var isRed =
        UiBase.isNotSame(value, oldValue, isForceCompare: isForceCompare);
    Widget child;
    TextStyle textStyle = AppStyle.textStyleWithCard();
    TextStyle textStyleRed = AppStyle.textStyleWithCardRed();
    List<Widget> children = [];
    if (isRed) {
      if (StringUtils.isEmpty(value)) {
        value = "(  )"; //fixme 子所以加括号空格。是因为显示（  ）比空字符串要好看。
      }
      if (StringUtils.isEmpty(oldValue)) {
        oldValue = "  "; //fixme 子所以加空格。是因为显示（  ）比（）要好看。
      }
      if (horizon) {
        //水平排列
        child = RichText(
            text: TextSpan(text: '$value', style: textStyle, children: [
          TextSpan(text: '($oldValue)', style: textStyleRed),
        ]));
        children.add(child);
      } else {
        //垂直排列
        child = Text('$value', style: textStyle);
        children.add(child);
        children.add(Text('($oldValue)', style: textStyleRed));
      }
    } else {
      child = Text(
        "$value",
        style: textStyle,
      );
      children.add(child);
    }
    Widget box;
    if (horizon) {
      //水平排列
      if (isCenter) {
        box = Row(
          children: children,
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
        );
      } else {
        box = Row(
          children: children,
        );
      }
    } else {
      //垂直排列
      if (isCenter) {
        box = Column(
          children: children,
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
        );
      } else {
        box = Column(
          children: children,
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
        );
      }
    }
    if (isCenter) {
      return Container(
        // padding: EdgeInsets.only(top: 4),
        alignment: Alignment.center,
        child: ConstrainedBox(
          child: box,
          constraints: BoxConstraints(
            minWidth: 100, //最小宽度
            minHeight: 30.0, //最小高度
          ),
        ),
      );
    } else {
      return Container(
        // padding: EdgeInsets.only(top: 4),
        alignment: Alignment.topLeft,
        child: ConstrainedBox(
          child: box,
          constraints: BoxConstraints(
            minWidth: 100, //最小宽度
            minHeight: 30.0, //最小高度
          ),
        ),
      );
    }
  }

  ///单行选中按钮
  ///isEnableCheck 是否开启选中能力。开启之后，会回调选中状态。
  static Widget itemWithCheckBox(BuildContext context, String? key,
      bool? isCheck, ValueChanged<bool?>? onChanged, bool isEnableCheck) {
    var textKey = Text(
      key ?? "",
      style: AppStyle.textStyleWithCard(),
    );
    //单选按钮
    var stateful = StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        return Checkbox(
          value: isCheck ?? false,
          //value 是否选中
          tristate: false,
          //默认false(只有选中和未选中两种状态); tristate（三态）如果为 true，那么复选框的值可以是 true，false 或 null。(多了一个null状态)
          // activeColor: Colors.red,
          // //activeColor 选中时背景颜色
          // checkColor: Colors.blue,
          // //checkColor 选中时打勾颜色
          // fillColor: MaterialStateProperty.all(Colors.black),
          //fixme fillColor 未选中时颜色; activeColor 会失效。
          onChanged: (value) {
            if (isEnableCheck) {
              setState(() {
                isCheck = value;
                onChanged?.call(value);
              });
            }
          },
        );
      },
    );

    var row = Row(
      children: [
        Container(
          alignment: Alignment.centerLeft,
          child: stateful,
          width: _width,
        ),
        Expanded(child: textKey)
      ],
    );
    return Padding(
      padding: EdgeInsets.only(top: _padding),
      child: row,
    );
  }

  ///isEnableCheck 是否开启选中能力。开启之后，会回调选中状态。
  static Widget checkBox(BuildContext context, String? key, bool? isCheck,
      ValueChanged<bool?>? onChanged, bool isEnableCheck) {
    var textKey = Text(
      key ?? "",
      style: AppStyle.textStyleWithCard(),
    );
    //单选按钮
    var stateful = StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        return Checkbox(
          value: isCheck ?? false,
          //value 是否选中
          tristate: false,
          //默认false(只有选中和未选中两种状态); tristate（三态）如果为 true，那么复选框的值可以是 true，false 或 null。(多了一个null状态)
          // activeColor: Colors.red,
          // //activeColor 选中时背景颜色
          // checkColor: Colors.blue,
          // //checkColor 选中时打勾颜色
          // fillColor: MaterialStateProperty.all(Colors.black),
          //fixme fillColor 未选中时颜色; activeColor 会失效。
          onChanged: (value) {
            if (isEnableCheck) {
              setState(() {
                isCheck = value;
                onChanged?.call(value);
              });
            }
          },
        );
      },
    );

    var row = Row(
      children: [
        Container(
          alignment: Alignment.center,
          child: stateful,
          // width: _width,
        ),
        textKey
      ],
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,
    );
    return Padding(
      padding: EdgeInsets.only(top: _padding),
      child: row,
    );
  }

  ///按钮
  ///value 文本
  ///onTap 点击事件
  static Widget itemWithButon(
      BuildContext context, String? value, VoidCallback? onPressed,
      {EdgeInsetsGeometry? margin = null, bool textStyleRed = false}) {
    TextStyle textStyle = AppStyle.textStyleWithButtonLittle();
    if (textStyleRed) {
      textStyle = AppStyle.textStyleWithButtonLittleRed();
    }
    var textValue = Text(
      value ?? "",
      softWrap: true,
      maxLines: 3,
      style: textStyle,
    );
    var row = Row(
      children: [
        MaterialButton(
          onPressed: onPressed,
          padding: EdgeInsets.only(left: 16, right: 16, top: 0, bottom: 0),
          height: 32,
          child: textValue,
          color: Colors.blueAccent,
        )
      ],
    );
    if (margin != null) {
      return Padding(
        padding: margin,
        child: row,
      );
    } else {
      return Padding(
        padding: EdgeInsets.only(top: _padding),
        child: row,
      );
    }
  }

  static Widget itemWithIcon(BuildContext context, String? key, String? url,
      {GestureTapCallback? onTap}) {
    if (StringUtils.isEmpty(url)) {
      return AppUi.getEmptyView(); //数据为空，返回空布局。
    }
    var textKey = Text(
      key ?? "",
      style: AppStyle.textStyleWithCard(),
    );
    var row = Row(
      children: [
        SizedBox(
          child: textKey,
          width: _width,
        ),
        icon(context, url, onTap: onTap)
      ],
    );
    return Padding(
      padding: EdgeInsets.only(top: _padding),
      child: row,
    );
  }

  ///小图标显示
  static Widget icon(BuildContext? context, String? url,
      {GestureTapCallback? onTap}) {
    if (StringUtils.isEmpty(url)) {
      return AppUi.getEmptyView();
    }
    return InkWell(
      child: Image.network(
        url!,
        height: 40,
      ),
      onTap: () {
        onTap?.call();
      },
    );
  }

  ///垂直布局
  static Widget column(BuildContext context, List<Widget> children) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: children,
    );
  }

  ///水平布局
  static Widget row(BuildContext context, List<Widget> children) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: children,
    );
  }

  ///ListView
  static ListView listView(BuildContext context, List<Widget> children) {
    return ListView(
        physics: BouncingScrollPhysics(),
        children: children,
        padding: EdgeInsets.only(bottom: _padding));
  }
}
